﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MsBuild = Microsoft.Build.Evaluation;
using Microsoft.Build.Construction;
using Genuilder.Extensibility;
using Microsoft.Build.Framework;

namespace Genuilder
{
	public class Project
	{
		readonly string _Path;
		public Project(string path)
		{
			if(path == null)
				throw new ArgumentNullException("path");
			_Path = path;
			_MsBuildData = new MSBuildData(this);
			CommonFeaturesPath = "";
		}


		public String Name
		{
			get
			{
				return System.IO.Path.GetFileName(_Path);
			}
		}

		public string Path
		{
			get
			{
				return _Path;
			}
		}

		public String CommonFeaturesPath
		{
			get;
			set;
		}

		
		private readonly MSBuildData _MsBuildData;
		public MSBuildData MsBuildData
		{
			get
			{
				return _MsBuildData;
			}
		}


		public void UnInstallFeatures()
		{
			_MsBuildData.UnInstallFeatures();
		}
		public void InstallFeature(Feature feature)
		{
			feature.LoadFeature(this, _MsBuildData);
		}
		public void InstallCommonFeature(CommonFeature feature)
		{
			InstallFeature(new TargetFeature(GetFullPath(_CommonFeature.GetFileName(feature), feature)));
		}

		private string GetFullPath(string file, CommonFeature feature)
		{
			var fullPath = file;
			if(!String.IsNullOrEmpty(CommonFeaturesPath))
			{
				fullPath = System.IO.Path.Combine(CommonFeaturesPath, file);
			}
			if(!File.Exists(fullPath))
			{
				throw new FileNotFoundException(Messages.TargetFileNotFoundForFeature(fullPath, feature.ToString()));
			}
			return fullPath;
		}


		public void Save()
		{
			_MsBuildData.ProjectRootElement.Save();
		}

		class Logger : ILogger
		{
			private readonly BuildResult _BuildResult = new BuildResult();
			public BuildResult BuildResult
			{
				get
				{
					return _BuildResult;
				}
			}
			#region ILogger Members

			public void Initialize(IEventSource eventSource)
			{
				eventSource.ErrorRaised += (s, a) => BuildResult.AddError(a);
			}

			public string Parameters
			{
				get;
				set;
			}

			public void Shutdown()
			{

			}

			public LoggerVerbosity Verbosity
			{
				get;
				set;
			}

			#endregion
		}

		public BuildResult Build()
		{
			var logger = new Logger();
			logger.BuildResult._Success = new MsBuild.Project(_Path, null, null, new MsBuild.ProjectCollection()).Build(logger);
			return logger.BuildResult;
		}

		public string RelativePathTo(string file)
		{
			file = new FileInfo(file).FullName;
			return PathUtil.RelativePathTo(new FileInfo(_Path).Directory.FullName, file);
		}

		public override string ToString()
		{
			return Name;
		}
	}

	public class BuildResult
	{
		internal bool _Success;
		public bool Success
		{
			get
			{
				return _Success;
			}
		}

		private readonly List<BuildErrorEventArgs> _Errors = new List<BuildErrorEventArgs>();
		public List<BuildErrorEventArgs> Errors
		{
			get
			{
				return _Errors;
			}
		}
		internal void AddError(BuildErrorEventArgs a)
		{
			_Errors.Add(a);
			_Success = false;
		}
	}
}
